package com.micromall.admin;

import com.google.common.collect.Maps;
import com.micromall.repository.FreightTemplateMapper;
import com.micromall.repository.GoodsMapper;
import com.micromall.repository.entity.Goods;
import com.micromall.repository.entity.common.ProductParamsKeys;
import com.micromall.repository.entity.common.PromotionConfigKeys;
import com.micromall.service.TransactionalExecuteService;
import com.micromall.utils.*;
import com.micromall.web.resp.ResponseEntity;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by zhangzx on 16/3/21.
 * 商品管理
 */
@RestController
@RequestMapping(value = "/admin/goods")
public class AdminGoodsController extends AdminBasicController {

	@Resource
	private GoodsMapper                 goodsMapper;
	@Resource
	private FreightTemplateMapper       freightTemplateMapper;
	@Resource
	private TransactionalExecuteService transactionalExecuteService;

	/**
	 * 商品列表
	 *
	 * @param query
	 * @param categoryId
	 * @param shelves
	 * @param promotion
	 * @param pageSize
	 * @param pageNo
	 * @return
	 */
	@RequestMapping(value = "/list")
	@Transactional(readOnly = true)
	public ResponseEntity<?> list(String query, Integer categoryId, Integer shelves, Boolean promotion, @RequestParam(defaultValue = "1") int pageNo,
			Integer pageSize) {
		Map<String, Object> params = Maps.newHashMap();
		params.put("orderBy", "id desc");
		if (StringUtils.isNotBlank(query)) {
			params.put("query", query);
		}
		if (null != shelves) {
			params.put("shelves", shelves == 1 ? true : false);
		}
		if (null != promotion) {
			params.put("promotion", promotion);
		}
		if (null != categoryId) {
			params.put("categoryId", categoryId);
		}
		return ResponseEntity.SuccessPage(goodsMapper.selectAdminPage(params, new RowBounds(pageNo, resizeLimit(pageSize))));
	}

	/**
	 * 商品详情
	 *
	 * @param id 商品id
	 * @return
	 */
	@RequestMapping(value = "/details")
	@Transactional(readOnly = true)
	public ResponseEntity<?> details(int id) {
		return ResponseEntity.Success(goodsMapper.selectAdminDetails(id));
	}

	@RequestMapping(value = "/upload_image")
	public ResponseEntity<?> upload_image(MultipartFile file) {
		String url = UploadUtils.upload(CommonEnvConstants.UPLOAD_GOODS_IMAGES_DIR, file);
		if (StringUtils.isNotEmpty(url)) {
			return ResponseEntity.Success(url);
		}
		return ResponseEntity.Failure("上传图片失败");
	}

	/**
	 * @param title 标题
	 * @param images 图片，以 , 分割
	 * @param categoryId 商品类目
	 * @param price 商品销售价格
	 * @param presentPrice 商品现价，只有促销类型为：single:depreciate 时才传值
	 * @param discount 折扣，只有促销类型为：single:depreciate 时才传值
	 * @param inventory 库存
	 * @param shelves 是否上架
	 * @param promotionType 促销类型 （打折促销：single:discount 需要传商品折扣（discount），降价促销：single:depreciate 需要传商品现价（presentPrice））
	 * @param freightId 运费模板id
	 * @param descr 商品描述信息
	 * @param weight 商品重量
	 * @return
	 */
	@RequestMapping(value = "/add")
	@Transactional
	public ResponseEntity<?> add(String title, String images, int categoryId, float price, Float presentPrice, Float discount, int inventory,
			boolean shelves, String promotionType, int freightId, String descr, float weight) {
		Goods goods = createGoods(title, images, categoryId, price, presentPrice, discount, inventory, shelves, promotionType, freightId, descr,
				weight);
		goods.setType(0);
		goods.setSalesVolume(0);
		goods.setClicked(0);
		goods.setSort(0);
		goods.setDeleted(false);
		goods.setCreateTime(new Date());
		transactionalExecuteService.execute(() -> goodsMapper.insert(goods));
		return ResponseEntity.Success(goods.getId());
	}

	private Goods createGoods(String title, String images, int categoryId, float price, Float presentPrice, Float discount, int inventory,
			boolean shelves, String promotionType, int freightId, String descr, float weight) {
		if (StringUtils.isBlank(title)) {
			throw new ArgumentValidException("商品标题不能为空");
		}
		if (ValidateUtils.illegalTextLength(1, 100, title)) {
			throw new ArgumentValidException("商品标题长度超过限制");
		}
		if (StringUtils.isBlank(images)) {
			throw new ArgumentValidException("商品图片不能为空");
		}
		List<String> _images = Arrays.asList(images.split(","));
		for (String img : _images) {
			if (StringUtils.isBlank(img)) {
				throw new ArgumentValidException("商品图片无效");
			}
		}
		if (weight < 0) {
			throw new ArgumentValidException("商品重量输入不正确");
		}
		if (inventory < 0) {
			throw new ArgumentValidException("商品库存量输入不正确");
		}
		if (price <= 0) {
			throw new ArgumentValidException("商品价格必须大于0");
		}
		// 类目检查
		if (goodsMapper.hasCategory(categoryId) == 0) {
			throw new ArgumentValidException("商品类目不存在");
		}
		// 模板检查
		if (freightTemplateMapper.selectByPrimaryKey(freightId) == null) {
			throw new ArgumentValidException("运费模板不存在");
		}

		Goods goods = new Goods();
		goods.setTitle(title);
		goods.setImages(_images);
		goods.setMainImage(_images.get(0));
		goods.setCategoryId(categoryId);
		goods.setPrice(Scale.scale(2, price));
		goods.setOriginPrice(goods.getPrice());
		goods.setInventory(inventory);
		goods.setShelves(shelves);
		goods.setPromotion(false);
		goods.setPromotionParams(new HashMap<>());
		if (StringUtils.isNotBlank(promotionType)) {
			goods.setPromotion(true);
			Map<String, Object> params = Maps.newHashMap();
			if (promotionType.equals(PromotionConfigKeys.PROMOTION_TYPE_SINGLE_DISCOUNT)) {
				if (discount == null) {
					throw new ArgumentValidException("商品折扣不能为空");
				}
				String _discount = String.valueOf(discount);
				int index = _discount.indexOf(".");
				int precision = index != -1 ? _discount.length() - index - 1 : 0;
				if (discount <= 0 || discount >= 10 || precision > 1) {
					throw new ArgumentValidException("商品折扣输入不正确");
				}

				goods.setPrice(Scale.scale(2, goods.getOriginPrice().multiply(new BigDecimal(discount).divide(BigDecimal.TEN))));
				params.put("type", PromotionConfigKeys.PROMOTION_TYPE_SINGLE_DISCOUNT);
				params.put("discount", String.valueOf(discount));
				params.put("discountName", ((int)(discount * 10)) + "折");
			} else if (promotionType.equals(PromotionConfigKeys.PROMOTION_TYPE_SINGLE_DEPRECIATE)) {
				if (presentPrice == null) {
					throw new ArgumentValidException("商品现价不能为空");
				}
				if (presentPrice >= price) {
					throw new ArgumentValidException("商品现价必须小于原价");
				}
				goods.setPrice(Scale.scale(2, presentPrice));
				params.put("type", PromotionConfigKeys.PROMOTION_TYPE_SINGLE_DEPRECIATE);
				params.put("presentPrice", String.valueOf(goods.getPrice()));
				params.put("presentName", "立减" + (goods.getOriginPrice().subtract(goods.getPrice())) + "元");
			} else {
				throw new ArgumentValidException("商品促销类型错误");
			}
			goods.setPromotionParams(params);
		}
		goods.setFreightId(freightId);
		goods.setDescr(descr);
		goods.setProductParams(new ChainMap<>(ProductParamsKeys.WEIGHT, Scale.scale(1, weight)));

		return goods;
	}

	@RequestMapping(value = "/update")
	@Transactional
	public ResponseEntity<?> update(int id, String title, String images, int categoryId, float price, Float presentPrice, Float discount,
			int inventory, boolean shelves, String promotionType, int freightId, String descr, float weight) {
		Goods goods = createGoods(title, images, categoryId, price, presentPrice, discount, inventory, shelves, promotionType, freightId, descr,
				weight);
		goods.setId(id);
		goods.setUpdateTime(new Date());
		transactionalExecuteService.execute(() -> goodsMapper.updateByPrimaryKey(goods));
		return ResponseEntity.Success();
	}

	/**
	 * @param ids
	 * @param shelves
	 * @return
	 */
	@RequestMapping(value = "/shelves")
	@Transactional
	public ResponseEntity<?> shelves(String ids, boolean shelves) {
		if (StringUtils.isBlank(ids)) {
			throw new ArgumentValidException("参数错误");
		}
		transactionalExecuteService.execute(() -> {
			for (String id : ids.split(",")) {
				Goods goods = new Goods();
				goods.setId(Integer.valueOf(id));
				goods.setShelves(shelves);
				goods.setUpdateTime(new Date());
				goodsMapper.updateByPrimaryKey(goods);
			}
		});
		return ResponseEntity.Success();
	}

	@RequestMapping(value = "/delete")
	@Transactional
	public ResponseEntity<?> delete(String ids) {
		if (StringUtils.isBlank(ids)) {
			throw new ArgumentValidException("参数错误");
		}
		transactionalExecuteService.execute(() -> {
			for (String id : ids.split(",")) {
				goodsMapper.deleteByPrimaryKey(Integer.valueOf(id));
			}
		});
		return ResponseEntity.Success();
	}

}
